// CSS沙盒隔离系统
export class CSSSandbox {
  private static instance: CSSSandbox
  private styleCache = new Map<string, HTMLStyleElement>()
  private prefixCache = new Map<string, string>()

  private constructor() {
    this.initGlobalStyles()
  }

  public static getInstance(): CSSSandbox {
    if (!CSSSandbox.instance) {
      CSSSandbox.instance = new CSSSandbox()
    }
    return CSSSandbox.instance
  }

  // 初始化全局样式隔离
  private initGlobalStyles() {
    const globalStyle = document.createElement('style')
    globalStyle.id = 'css-sandbox-global'
    globalStyle.textContent = `
      /* 全局样式隔离 - 严格模式 */
      .css-sandbox {
        all: initial;
        font-family: inherit;
        line-height: inherit;
        color: inherit;
      }
      
      /* 微应用容器样式隔离 - 严格模式 */
      .micro-app-container {
        isolation: isolate;
        contain: layout style paint;
        /* 确保在严格隔离模式下容器样式正确 */
        position: relative;
        width: 100%;
        height: 100%;
        overflow: hidden;
      }
      
      /* 防止微应用样式影响全局 - 严格模式 */
      .micro-app-container * {
        box-sizing: border-box;
      }
      
      /* 微应用样式作用域 - 严格模式 */
      .micro-app-scoped {
        --app-prefix: '';
      }
      
      /* 确保主题变量能够传递到微应用 */
      .micro-app-container {
        /* 继承主题变量 */
        color: var(--text-color, #333333);
        background-color: var(--background-color, #fcfcfc);
      }
    `
    document.head.appendChild(globalStyle)
  }

  // 为微应用创建样式隔离
  public createSandbox(appName: string, container: HTMLElement): string {
    const prefix = `app-${appName}-`
    this.prefixCache.set(appName, prefix)
    
    // 为容器添加隔离类
    container.classList.add('micro-app-container', 'css-sandbox')
    container.setAttribute('data-app-name', appName)
    
    return prefix
  }

  // 注入微应用样式（带前缀）
  public injectStyles(appName: string, styles: string): void {
    const prefix = this.prefixCache.get(appName)
    if (!prefix) return

    // 移除旧的样式
    this.removeStyles(appName)

    // 创建新的样式元素
    const styleElement = document.createElement('style')
    styleElement.id = `micro-app-styles-${appName}`
    
    // 添加前缀到样式
    const prefixedStyles = this.addPrefixToStyles(styles, prefix)
    styleElement.textContent = prefixedStyles
    
    document.head.appendChild(styleElement)
    this.styleCache.set(appName, styleElement)
  }

  // 为样式添加前缀
  private addPrefixToStyles(styles: string, prefix: string): string {
    // 简单的CSS选择器前缀处理
    return styles.replace(/([.#][a-zA-Z][a-zA-Z0-9_-]*)/g, `${prefix}$1`)
  }

  // 移除微应用样式
  public removeStyles(appName: string): void {
    const styleElement = this.styleCache.get(appName)
    if (styleElement) {
      styleElement.remove()
      this.styleCache.delete(appName)
    }
    this.prefixCache.delete(appName)
  }

  // 清理所有微应用样式
  public clearAllStyles(): void {
    this.styleCache.forEach((styleElement) => {
      styleElement.remove()
    })
    this.styleCache.clear()
    this.prefixCache.clear()
  }

  // 获取微应用前缀
  public getAppPrefix(appName: string): string {
    return this.prefixCache.get(appName) || ''
  }

  // 检查样式是否已注入
  public hasStyles(appName: string): boolean {
    return this.styleCache.has(appName)
  }
}

// 导出单例实例
export const cssSandbox = CSSSandbox.getInstance()

// 微应用样式管理器
export class MicroAppStyleManager {
  private static instance: MicroAppStyleManager
  private activeApps = new Set<string>()

  private constructor() {}

  public static getInstance(): MicroAppStyleManager {
    if (!MicroAppStyleManager.instance) {
      MicroAppStyleManager.instance = new MicroAppStyleManager()
    }
    return MicroAppStyleManager.instance
  }

  // 注册微应用样式
  public registerApp(appName: string, container: HTMLElement): void {
    if (this.activeApps.has(appName)) return

    const prefix = cssSandbox.createSandbox(appName, container)
    this.activeApps.add(appName)
    
    console.log(`[CSS Sandbox] 注册微应用样式: ${appName}, 前缀: ${prefix}`)
  }

  // 卸载微应用样式
  public unregisterApp(appName: string): void {
    if (!this.activeApps.has(appName)) return

    cssSandbox.removeStyles(appName)
    this.activeApps.delete(appName)
    
    console.log(`[CSS Sandbox] 卸载微应用样式: ${appName}`)
  }

  // 获取活跃的微应用列表
  public getActiveApps(): string[] {
    return Array.from(this.activeApps)
  }

  // 清理所有微应用样式
  public clearAll(): void {
    cssSandbox.clearAllStyles()
    this.activeApps.clear()
    console.log('[CSS Sandbox] 清理所有微应用样式')
  }
}

// 导出样式管理器实例
export const microAppStyleManager = MicroAppStyleManager.getInstance() 